package cn.hg.solon.youcan.common.web;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.text.CharSequenceUtil;
import org.dromara.hutool.core.util.ObjUtil;

import cn.hg.solon.youcan.common.constant.AppConstants;
import cn.hg.solon.youcan.common.vo.BaseVo;

/**
 * Layui TreeTable树表组件结果对象
 * <p>
 * https://layui.dev/docs/2.8/treeTable/
 * </p>
 * 
 * @author 胡高
 */
public class LayuiTreeTable<T extends Serializable> extends BaseVo {

    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = -6223923414201740449L;

    private static String CHILDREN = "children";
    private static String NAME = "name";

    /**
     * 结果代码
     */
    protected int code = 0;

    /**
     * 结果信息
     */
    protected String msg;

    /**
     * 数据总数
     */
    protected int count = 0;

    /**
     * 树对象数组
     */
    protected List<Map<String, Object>> data;

    /**
     * ID字段名
     */
    private String idField = "id";

    /**
     * 父ID字段名
     */
    private String parentIdField = "parentId";

    /**
     * 名称字段名
     */
    private String nameField = "name";

    public LayuiTreeTable(final Collection<T> beanList, final int totalRow, final Object initParentId) {
        this(beanList, CollUtil.isEmpty(beanList) ? 0 : beanList.size(), "id", "parentId", "name", initParentId);

        this.count = CollUtil.size(this.data);
    }

    public LayuiTreeTable(final Collection<T> beanList, final int totalRow, final String idField,
        final String parentIdField, final String nameField, final Object initParentId) {

        this.count = totalRow;

        this.idField = CharSequenceUtil.toCamelCase(idField);
        this.parentIdField = CharSequenceUtil.toCamelCase(parentIdField);
        this.nameField = CharSequenceUtil.toCamelCase(nameField);

        // 转换项目列表为树状选择项列表
        List<Map<String, Object>> itemList = this.convertToItemMap(beanList, initParentId);

        // 构建树状对象
        this.data = this.buildTree(itemList, initParentId);
    }

    public LayuiTreeTable(final int code, final String errorMessage) {
        this.code = code;
        this.msg = errorMessage;
    }

    public LayuiTreeTable(final String errorMessage) {
        this(AppConstants.RETURN_CODE_VALUE_FAILED, errorMessage);
    }

    private List<Map<String, Object>> buildTree(final Collection<Map<String, Object>> mapList, final Object parentId) {
        List<Map<String, Object>> list = new ArrayList<>();

        for (Map<String, Object> item : mapList) {
            if (ObjUtil.equals(parentId, item.get(this.parentIdField))) {
                list.add(item);
            }
        }

        for (Map<String, Object> item : list) {
            item.put(CHILDREN, this.buildTree(mapList, item.get(this.idField)));
        }

        return list;
    }

    private List<Map<String, Object>> convertToItemMap(final Collection<T> list, final Object initParentId) {
        List<Map<String, Object>> itemMap = new ArrayList<>();
        for (T item : list) {
            Map<String, Object> bean = BeanUtil.beanToMap(item);

            /*
             * name字段
             */
            if (!bean.containsKey(this.nameField)) {
                bean.put(NAME, this.nameField);
            }

            itemMap.add(bean);
        }

        return itemMap;
    }


    public List<Map<String, Object>> getData() {
        return this.data;
    }

    public void setData(List<Map<String, Object>> data) {
        this.data = data;
    }
}
